Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Drawing
Imports System.Data
Imports System.Text
Imports System.Windows.Forms

Namespace DgvFilterPopup


	''' <summary>
	''' A standard <i>column filter</i> implementation for ComboBox columns.
	''' </summary>
	''' <remarks>
	''' If the <b>DataGridView</b> column to which this <i>column filter</i> is applied
	''' is not a ComboBox column, it automatically creates a distinct list of values from the bound <b>DataView</b> column.
	''' If the DataView changes, you should do an explicit call to <see cref="DgvComboBoxColumnFilter.RefreshValues"/> method.
	''' </remarks>
	Public Partial Class DgvComboBoxColumnFilter
		Inherits DgvBaseColumnFilter

		''' <summary>
		''' Initializes a new instance of the <see cref="DgvComboBoxColumnFilter"/> class.
		''' </summary>
		Public Sub New()
			InitializeComponent()
            AddHandler m_comboBoxOperator.SelectedValueChanged, New EventHandler(AddressOf onFilterChanged)
            AddHandler m_comboBoxValue.SelectedValueChanged, New EventHandler(AddressOf onFilterChanged)
        End Sub

        ''' <summary>
        ''' Gets the ComboBox control containing the available operators.
        ''' </summary>
        Public ReadOnly Property ComboBoxOperator() As ComboBox
            Get
                Return m_comboBoxOperator
            End Get
        End Property


        ''' <summary>
        ''' Gets the ComboBox control containing the available values.
        ''' </summary>
        Public ReadOnly Property ComboBoxValue() As ComboBox
            Get
                Return m_comboBoxValue
            End Get
        End Property



        ''' <summary>
        ''' Perform filter initialitazion and raises the FilterInitializing event.
        ''' </summary>
        ''' <param name="sender">The source of the event.</param>
        ''' <param name="e">The <see cref="System.ComponentModel.CancelEventArgs"/> instance containing the event data.</param>
        ''' <remarks>
        ''' When this <i>column filter</i> control is added to the <i>column filters</i> array of the <i>filter manager</i>,
        ''' the latter calls the <see cref="DgvBaseColumnFilter.Init"/> method which, in turn, calls this method.
        ''' You can ovverride this method to provide initialization code or you can create an event handler and 
        ''' set the <i>Cancel</i> property of event argument to true, to skip standard initialization.
        ''' </remarks>
        Protected Overrides Sub OnFilterInitializing(sender As Object, e As CancelEventArgs)
            MyBase.OnFilterInitializing(sender, e)
            If e.Cancel Then
                Return
            End If
            m_comboBoxOperator.Items.AddRange(New Object() {"=", "<>", "= NULL", "<> NULL"})
            m_comboBoxOperator.SelectedIndex = 0
            If TypeOf Me.DataGridViewColumn Is DataGridViewComboBoxColumn Then
                m_comboBoxValue.ValueMember = DirectCast(DataGridViewColumn, DataGridViewComboBoxColumn).ValueMember
                m_comboBoxValue.DisplayMember = DirectCast(DataGridViewColumn, DataGridViewComboBoxColumn).DisplayMember
                m_comboBoxValue.DataSource = DirectCast(DataGridViewColumn, DataGridViewComboBoxColumn).DataSource
            Else
                m_comboBoxValue.ValueMember = Me.DataGridViewColumn.DataPropertyName
                m_comboBoxValue.DisplayMember = Me.DataGridViewColumn.DataPropertyName
                RefreshValues()
            End If
            Me.FilterHost.RegisterComboBox(m_comboBoxOperator)
            Me.FilterHost.RegisterComboBox(m_comboBoxValue)
        End Sub

        ''' <summary>
        ''' For non-combobox columns, refreshes the list of the <b>DataView</b> values in the column.
        ''' </summary>
        Public Sub RefreshValues()
            If Not (TypeOf Me.DataGridViewColumn Is DataGridViewComboBoxColumn) Then
                Dim DistinctDataTable As DataTable = Me.BoundDataView.ToTable(True, New String() {Me.DataGridViewColumn.DataPropertyName})
                DistinctDataTable.DefaultView.Sort = Me.DataGridViewColumn.DataPropertyName
                m_comboBoxValue.DataSource = DistinctDataTable
            End If
        End Sub


        ''' <summary>
        ''' Builds the filter expression and raises the FilterExpressionBuilding event
        ''' </summary>
        ''' <param name="sender">The event source.</param>
        ''' <param name="e">The <see cref="System.ComponentModel.CancelEventArgs"/> instance containing the event data.</param>
        ''' <remarks>
        ''' Override <b>OnFilterExpressionBuilding</b> to provide a filter expression construction
        ''' logic and to set the values of the <see cref="DgvBaseColumnFilter.FilterExpression"/> and <see cref="DgvBaseColumnFilter.FilterCaption"/> properties.
        ''' The <see cref="DgvFilterManager"/> will use these properties in constructing the whole filter expression and to change the header text of the filtered column.
        ''' Otherwise, you can create an event handler and set the <i>Cancel</i> property of event argument to true, to skip standard filter expression building logic.
        ''' </remarks>
        Protected Overrides Sub OnFilterExpressionBuilding(sender As Object, e As CancelEventArgs)
            MyBase.OnFilterExpressionBuilding(sender, e)
            If e.Cancel Then
                FilterManager.RebuildFilter()
                Return
            End If

            Dim ResultFilterExpression As String = ""
            Dim ResultFilterCaption As String = OriginalDataGridViewColumnHeaderText

            ' Managing the NULL and NOT NULL cases which are type-independent
            If m_comboBoxOperator.Text = "= NULL" Then
                ResultFilterExpression = GetNullCondition(Me.DataGridViewColumn.DataPropertyName)
            End If
            If m_comboBoxOperator.Text = "<> NULL" Then
                ResultFilterExpression = GetNotNullCondition(Me.DataGridViewColumn.DataPropertyName)
            End If

            If ResultFilterExpression <> "" Then
                FilterExpression = ResultFilterExpression
                FilterCaption = (ResultFilterCaption & vbLf & " ") + m_comboBoxOperator.Text
                FilterManager.RebuildFilter()
                Return
            End If

            Dim FilterValue As Object = m_comboBoxValue.SelectedValue
            Dim FormattedValue As String = ""

            If ColumnDataType = GetType(String) Then
                ' Managing the string-column case
                Dim EscapedFilterValue As String = StringEscape(FilterValue.ToString())
                ResultFilterExpression = (Convert.ToString(Me.DataGridViewColumn.DataPropertyName) & " ") + m_comboBoxOperator.Text & "'" & EscapedFilterValue & "'"
                ResultFilterCaption += (vbLf + m_comboBoxOperator.Text & " ") + m_comboBoxValue.Text
            Else
                ' Managing the other cases
                FormattedValue = FormatValue(FilterValue, Me.ColumnDataType)
                If FormattedValue <> "" Then
                    ResultFilterExpression = (Convert.ToString(Me.DataGridViewColumn.DataPropertyName) & " ") + m_comboBoxOperator.Text & FormattedValue
                    ResultFilterCaption += (vbLf + m_comboBoxOperator.Text & " ") + m_comboBoxValue.Text

                End If
            End If
            If ResultFilterExpression <> "" Then
                FilterExpression = ResultFilterExpression
                FilterCaption = ResultFilterCaption
                FilterManager.RebuildFilter()
            End If
        End Sub

		Private Sub onFilterChanged(sender As Object, e As EventArgs)
			If Not FilterApplySoon OrElse Not Me.Visible Then
				Return
			End If
			Active = True
			FilterExpressionBuild()

		End Sub





	End Class
End Namespace
